package core;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;

enum Secuence {
	NONE, ASC, DESC
};

public class Cartoons {

	private Hashtable<String, Integer> characters;
	private final int NUMCARTOONS = 50;

	public Cartoons() {
		characters = new Hashtable<String, Integer>();
	}

	public void collectCartoons(String inputPath,String outputPath) throws IOException {

		File root = new File(inputPath);
		File[] files = root.listFiles();
		// Writes file characters.txt
		BufferedWriter bw;
		bw = new BufferedWriter(new FileWriter(outputPath+"allCartoons.txt"));
		
		// List to store the cartoons less popular
		ArrayList<String> lLessCartoons = new ArrayList<String>();
		int numCartoons = 0;

		// Array with the goal of string the index of the ranking
		int[] arrayIndex = new int[1];
		// Enum to know the sequence to execute
		Secuence[] arraySequence = { Secuence.NONE };
		boolean[] arrayInitIndex = { false };

		for (int i = 0; i < files.length; i++) {
			if (files[i].isDirectory())
				continue;

			if (i != 0)
				bw.newLine();

			arrayIndex[0] = 1;
			BufferedReader br = new BufferedReader(new FileReader(files[i]));
			String line = br.readLine();
			boolean fin = false;
			arrayInitIndex[0] = false;
			arraySequence[0] = Secuence.NONE;
			// Reads the lines of the file
			while (line != null && fin == false) {

				fin = checkValidLines(line, arrayIndex, arraySequence, bw,
						arrayInitIndex);
				line = br.readLine();

			}
			br.close();
			bw.flush();
		}

		
		

		// This file contains the cartoons selected by rate
		bw = new BufferedWriter(new FileWriter(outputPath+"cartoonsSelected.txt"));

		Enumeration<String> keys = characters.keys();
		while (keys.hasMoreElements()) {
			String clave = keys.nextElement();
			int times = characters.get(clave);
			if (times > 1) {
				bw.write(clave);
				
				bw.newLine();
				numCartoons++;
			} else {
				lLessCartoons.add(clave);
			
			}

			

			
		}
		
		

		// Stores the cartoons until gets the 50 cartoons
		for (int i = 0; i < lLessCartoons.size() && numCartoons < NUMCARTOONS; i++) {
			String cartoon = lLessCartoons.get(i);
			bw.write(cartoon);
			if (numCartoons != NUMCARTOONS - 1)
				bw.newLine();
			numCartoons++;
		}
		// Save the data in the file

		bw.flush();

	}

	private boolean checkValidLines(String line, int[] arrayIndex,
			Secuence[] secuencia, BufferedWriter bw, boolean[] arrayInitIndex)
			throws IOException {
		boolean fin = false;
		boolean init = true;
		String delimitadores = "[ .,;?\t\n|!¡¿\'\"\\[\\]]+";
		String[] words = line.split(delimitadores);

		if (words.length > 1) {
			if (digitWord(words) != -1) {
				int index = digitWord(words);
				int currentIndex = Integer.parseInt(words[index]);
				if (!arrayInitIndex[0]) {
					arrayIndex[0] = currentIndex;
					arrayInitIndex[0] = true;
				} else
					init = false;

				decideSequence(currentIndex, secuencia);
				fin = orderSequence(secuencia, arrayIndex, currentIndex);
				if (!fin)
					storeCharacters(words, index, bw, init);

			}
		}

		return fin;
	}

	private void decideSequence(int index, Secuence[] secuencia) {

		if (secuencia[0] == Secuence.NONE) {

			if (index > 1)
				secuencia[0] = Secuence.DESC;
			else
				secuencia[0] = Secuence.ASC;

		}

	}

	private boolean orderSequence(Secuence[] secuencia, int[] arrayIndex,
			int currentIndex) {

		switch (secuencia[0]) {
		case ASC:
			return executeAsc(arrayIndex, currentIndex);

		case DESC:
			return executeDesc(arrayIndex, currentIndex);

		default:
			return false;

		}
	}

	private boolean executeAsc(int[] arrayIndex, int currentIndex) {

		if (arrayIndex[0] == currentIndex) {
			arrayIndex[0]++;
			return false;
		} else
			return true;
	}

	private boolean executeDesc(int[] arrayIndex, int currentIndex) {

		if (arrayIndex[0] > 0 && arrayIndex[0] == currentIndex) {
			arrayIndex[0]--;
			return false;
		} else
			return true;
	}

	private void storeCharacters(String[] words, int index, BufferedWriter bw,
			boolean init) throws IOException {

		StringBuilder name = new StringBuilder();

		for (int i = ++index; i < words.length; i++) {
			if(i==words.length-1)
			name.append(words[i]);
			else{
				name.append(words[i]);
				name.append(" ");
			}

		}

		if (!characters.containsKey(name.toString())) {
			characters.put(name.toString(), 1);
			if (!init)
				bw.newLine();
			bw.write(name.toString());

		} else {

			characters
					.put(name.toString(), characters.get(name.toString()) + 1);
		}

	}

	private int digitWord(String[] cadena) {
		int isaDigit = -1;
		for (int i = 0; i < cadena.length; i++) {
			if (cadena[i].isEmpty()) {
				continue;
			} else {
				char[] caracteres = cadena[i].toCharArray();
				if (caracteres.length > 0) {
					// Check the number
					if (checkDigit(caracteres)) {
						if (++i < cadena.length) {
							char[] word = cadena[i].toCharArray();
							if (Character.isLetter(word[0])) {
								isaDigit = --i;
								break;
							} else
								break;
						} else
							break;

					} else
						break;
				}
			}

		}

		return isaDigit;
	}

	private boolean checkDigit(char[] word) {
		if (word.length > 0) {
			for (int i = 0; i < word.length; i++) {
				if (!Character.isDigit(word[i]))
					return false;
			}
		}
		return true;
	}

}
